home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / flight / exp.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  17KB  |  767 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /*
  19.  *  flight/exp.c $Revision: 1.6 $
  20.  *
  21.  *  code for drawing explosions and missiles
  22.  */
  23.  
  24. #include <math.h>
  25. #include "flight.h"
  26. #include "light.h"
  27.  
  28. int expv_cols[55];
  29. float expv[55][3] = {{0.967742, 0.000000, -1.612903},
  30.              {1.129032, 0.838710, 0.967742},
  31.              {0.612903, 1.629032, 0.577419},
  32.              {0.161290, -1.048387, -1.367742},
  33.              {1.267742, -0.174194, 1.212903},
  34.              {-1.129032, 0.835484, -0.967742},
  35.              {1.277419, -1.296774, -0.270968},
  36.              {1.038710, -0.664516, -1.141935},
  37.              {0.806452, 0.538710, 1.729032},
  38.              {-0.706452, 0.151613, 1.729032},
  39.              {-1.374194, -0.793548, 0.309677},
  40.              {0.961290, 1.483871, -0.348387},
  41.              {-1.451613, 0.280645, 0.967742},
  42.              {0.000000, 0.000000, -1.935484},
  43.              {0.000000, 1.767742, -0.309677},
  44.              {-1.525806, -0.300000, -0.880645},
  45.              {-1.129032, 1.396774, -0.967742},
  46.              {0.806452, 1.396774, -0.967742},
  47.              {0.483871, 0.838710, -1.612903},
  48.              {0.806452, -1.396774, 0.967742},
  49.              {1.129032, 0.838710, -0.967742},
  50.              {0.161290, 1.048387, 1.367742},
  51.              {-0.180645, 1.641935, 0.683871},
  52.              {0.551613, -0.667742, -1.674194},
  53.              {-0.812903, -1.587097, 0.619355},
  54.              {-1.380645, -0.693548, -0.464516},
  55.              {-0.483871, 0.629032, -1.858065},
  56.              {-1.606452, 0.367742, -0.348387},
  57.              {-0.967742, 1.677419, 0.000000},
  58.              {-0.806452, -1.261290, -1.125806},
  59.              {0.000000, -1.587097, 0.309677},
  60.              {-0.812903, -1.767742, 0.000000},
  61.              {1.670968, 0.283871, 0.306452},
  62.              {-0.161290, 1.261290, -1.125806},
  63.              {0.161290, -1.487097, -0.658064},
  64.              {0.967742, -1.677419, 0.000000},
  65.              {0.645161, -0.558065, 1.612903},
  66.              {1.522581, -0.693548, 0.038710},
  67.              {-1.380645, 0.693548, 0.464516},
  68.              {0.806452, -1.396774, -0.967742},
  69.              {0.483871, -0.974194, 1.454839},
  70.              {0.161290, -0.235484, 1.845161},
  71.              {-0.161290, -0.538710, 1.729032},
  72.              {-0.693548, 1.200000, 1.196774},
  73.              {-0.409677, -1.309677, 1.070968},
  74.              {1.545161, -0.258065, -0.825806},
  75.              {-1.935484, 0.000000, 0.000000},
  76.              {-0.829032, -0.664516, 1.367742},
  77.              {-0.161290, -0.838710, -1.612903},
  78.              {-0.161290, 0.538710, 1.729032},
  79.              {-1.070968, -0.300000, -1.338710},
  80.              {-0.680645, 0.316129, -1.770968},
  81.              {1.606452, 0.367742, -0.348387},
  82.              {-1.303226, 1.125806, 0.048387},
  83.              {1.438710, 1.016129, 0.270968}};
  84.  
  85.  
  86. #define EXP_TRI 106
  87. int expref[EXP_TRI][3] = {{40, 41, 42},
  88.               {40, 42, 44},
  89.               {44, 42, 47},
  90.               {47, 42,  9},
  91.               { 9, 42, 49},
  92.               {49, 42, 41},
  93.               { 8, 49, 41},
  94.               { 8, 41, 36},
  95.               {36, 41, 40},
  96.               {40, 44, 19},
  97.               { 4, 40, 19},
  98.               {40,  4, 36},
  99.               {36,  4,  8},
  100.               { 8,  4,  1},
  101.               { 1,  4, 32},
  102.               {32,  4, 37},
  103.               {37,  4, 19},
  104.               { 6, 37, 19},
  105.               {45, 37,  6},
  106.               {37, 45, 52},
  107.               {52, 32, 37},
  108.               {52, 11, 54},
  109.               {32, 52, 54},
  110.               {54,  1, 32},
  111.               {54,  2,  1},
  112.               {54, 11,  2},
  113.               {21,  1,  2},
  114.               { 8,  1, 21},
  115.               {21, 49,  8},
  116.               {43, 49, 21},
  117.               {43, 21, 22},
  118.               {22, 21,  2},
  119.               {49, 43, 12},
  120.               { 9, 49, 12},
  121.               {12, 47,  9},
  122.               {10, 47, 12},
  123.               {24, 47, 10},
  124.               {44, 47, 24},
  125.               {44, 24, 30},
  126.               {30, 19, 44},
  127.               {30, 24, 31},
  128.               {31, 24, 10},
  129.               {34, 30, 31},
  130.               {35, 30, 34},
  131.               {19, 30, 35},
  132.               {19, 35,  6},
  133.               {35, 34, 39},
  134.               { 6, 35, 39},
  135.               { 6, 39, 45},
  136.               {45, 39,  7},
  137.               { 0, 45,  7},
  138.               { 0,  7, 23},
  139.               { 3, 23,  7},
  140.               { 3,  7, 39},
  141.               {39, 34,  3},
  142.               {13,  0, 23},
  143.               {48, 13, 23},
  144.               {23,  3, 48},
  145.               { 3, 29, 48},
  146.               {34, 29,  3},
  147.               {31, 29, 34},
  148.               {25, 29, 31},
  149.               {31, 10, 25},
  150.               {10, 46, 25},
  151.               {12, 46, 10},
  152.               {20, 52, 45},
  153.               {11, 52, 20},
  154.               {20, 45,  0},
  155.               {29, 15, 50},
  156.               {29, 50, 48},
  157.               {29, 25, 15},
  158.               {27, 15, 25},
  159.               {25, 46, 27},
  160.               {27,  5, 15},
  161.               { 5, 50, 15},
  162.               {48, 50, 51},
  163.               {48, 51, 13},
  164.               {51, 50,  5},
  165.               {53,  5, 27},
  166.               {38, 53, 27},
  167.               {27, 46, 38},
  168.               {38, 46, 12},
  169.               {43, 38, 12},
  170.               {28, 53, 38},
  171.               {22, 38, 43},
  172.               {28, 38, 22},
  173.               {22,  2, 14},
  174.               {22, 14, 28},
  175.               {14,  2, 11},
  176.               {16,  5, 53},
  177.               {53, 28, 16},
  178.               {16, 28, 14},
  179.               {14, 11, 17},
  180.               {11, 20, 17},
  181.               { 0, 13, 18},
  182.               {13, 26, 18},
  183.               {13, 51, 26},
  184.               {18, 26, 33},
  185.               {18, 20,  0},
  186.               {18, 17, 20},
  187.               {33, 17, 18},
  188.               {14, 17, 33},
  189.               {14, 33, 16},
  190.               {16, 33,  5},
  191.               {26, 51,  5},
  192.               { 5, 33, 26}};
  193.  
  194.  
  195. unsigned long exp_cp[160];
  196.  
  197. float **exp_p;
  198.  
  199. float exp_pnt[100][4];
  200.  
  201. float n_up[4] = {0.0, 1.0, 0.0, 0.0};
  202.  
  203.  
  204. static unsigned short exp_pats[] =
  205. /* 15 / 16 */
  206.    { 0x8888, 0xffff, 0xffff, 0xffff, 0x8888, 0xffff, 0xffff, 0xffff,
  207.      0x8888, 0xffff, 0xffff, 0xffff, 0x8888, 0xffff, 0xffff, 0xffff,
  208. /* 12 / 16 */
  209.      0xafaf, 0xfafa, 0x5f5f, 0xf5f5, 0xafaf, 0xfafa, 0x5f5f, 0xf5f5,
  210.      0xafaf, 0xfafa, 0x5f5f, 0xf5f5, 0xafaf, 0xfafa, 0x5f5f, 0xf5f5,
  211. /* 8 / 16 */
  212.      0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa,
  213.      0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa,
  214. /* 4 / 16 */
  215.      0x5050, 0x0505, 0xa0a0, 0x0a0a, 0x5050, 0x0505, 0xa0a0, 0x0a0a,
  216.      0x5050, 0x0505, 0xa0a0, 0x0a0a, 0x5050, 0x0505, 0xa0a0, 0x0a0a,
  217. /* 1 / 16 */
  218.      0x1111, 0x0000, 0x0000, 0x0000, 0x2222, 0x0000, 0x0000, 0x0000,
  219.      0x4444, 0x0000, 0x0000, 0x0000, 0x8888, 0x0000, 0x0000, 0x0000,
  220. /* 0 / 16 */
  221.      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  222.      0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
  223.  
  224.  
  225. init_exp()
  226. {
  227.     int red_1 = 0xff;
  228.     int red_2 = 0xcc;
  229.     int red_3 = 0x00;
  230.     int red_4 = 0x00;
  231.     int green_1 = 0x88;
  232.     int green_2 = 0x11;
  233.     int green_3 = 0x00;
  234.     int green_4 = 0x00;
  235.     int alpha_1 = 0xff;
  236.     int alpha_2 = 0xff;
  237.     int alpha_3 = 0x99;
  238.     int alpha_4 = 0x11;
  239.     unsigned long cur_red, cur_green, cur_alpha;
  240.     int i;
  241.     float delta, idelta;
  242.  
  243.     /*
  244.      *  color index setup
  245.      */
  246.     for (i=0; i<55; i++)
  247.     {
  248.     expv_cols[i] = (i%2 == 0)? ci_table[C_RED] : ci_table[C_DRED];
  249.     }
  250.     for (i=0; i<5; i++)
  251.     {
  252.     defpattern(EXPL_PAT0+i, 16, &(exp_pats[(i<<4)&0xf0]));
  253.     }
  254.     defpattern(3, 16, &(exp_pats[32]));
  255.  
  256.     /*
  257.      *  rgb setup
  258.      */
  259.     for (i = 0; i < 50; i++)
  260.     {
  261.     delta = i / 49.0;
  262.     idelta = 1.0-delta;
  263.  
  264.     cur_red = red_1 * idelta + red_2 * delta;
  265.     cur_green = green_1 * idelta + green_2 * delta;
  266.     cur_alpha = alpha_1 * idelta + alpha_2 * delta;
  267.  
  268.     exp_cp[i] = (cur_alpha << 24) + (cur_green << 8) + cur_red;
  269.     }
  270.  
  271.     for (i = 50; i < 100; i++)
  272.     {
  273.     delta = (i-50) / 49.0;
  274.     idelta = 1.0-delta;
  275.  
  276.     cur_red = red_2 * idelta + red_3 * delta;
  277.     cur_green = green_2 * idelta + green_3 * delta;
  278.     cur_alpha = alpha_2 * idelta + alpha_3 * delta;
  279.  
  280.     exp_cp[i] = (cur_alpha << 24) + (cur_green << 8) + cur_red;
  281.     }
  282.  
  283.     for (i = 100; i < 150; i++)
  284.     {
  285.     delta = (i-100) / 49.0;
  286.     idelta = 1.0-delta;
  287.  
  288.     cur_red = red_3 * idelta + red_4 * delta;
  289.     cur_green = green_3 * idelta + green_4 * delta;
  290.     cur_alpha = alpha_3 * idelta + alpha_4 * delta;
  291.  
  292.     exp_cp[i] = (cur_alpha << 24) + (cur_green << 8) + cur_red;
  293.     }
  294.  
  295.     exp_p = (float **)malloc(sizeof(float *) * EXP_TRI * 3);
  296.     for (i = 0; i < EXP_TRI*3; i += 3)
  297.     {
  298.     exp_p[i] = expv[expref[i/3][0]];
  299.     exp_p[i+1] = expv[expref[i/3][1]];
  300.     exp_p[i+2] = expv[expref[i/3][2]];
  301.     }
  302.  
  303.     for (i = 0; i < 100; i++)
  304.     {
  305.     exp_pnt[i][0] = flight_random(1000) / 250.0;
  306.     exp_pnt[i][1] = flight_random(1000) / 250.0;
  307.     exp_pnt[i][2] = flight_random(1000) / 250.0;
  308.     }
  309. }
  310.  
  311.  
  312. draw_exp(int frame)
  313. {
  314.     int i, c;
  315.     float s;
  316.     float **p, *v;
  317.  
  318.     pushmatrix();
  319.  
  320.     s = (frame + 1.0) * 3.0;
  321.     scale(s, s, s);
  322.  
  323.     cpack(0xff0055ff);
  324.     bgnpoint();
  325.     for (i = 0, v = exp_pnt[0]; i < 100; i+=10, v += 10)
  326.     {
  327.     v3f(v);
  328.     v3f(v+1);
  329.     v3f(v+2);
  330.     v3f(v+3);
  331.     v3f(v+4);
  332.     v3f(v+5);
  333.     v3f(v+6);
  334.     v3f(v+7);
  335.     v3f(v+8);
  336.     v3f(v+9);
  337.     }
  338.     endpoint();
  339.  
  340.     zwritemask(0x0);
  341.     blendfunction(BF_SA, BF_MSA);
  342.  
  343.     for (i=0, p = exp_p; i < EXP_TRI; i++, p += 3)
  344.     {
  345.     c = frame * 5;
  346.  
  347.     bgnpolygon();
  348.     cpack(exp_cp[expref[i][0] + c]);
  349.     v3f(*p);
  350.     cpack(exp_cp[expref[i][1] + c]);
  351.     v3f(*(p+1));
  352.     cpack(exp_cp[expref[i][2] + c]);
  353.     v3f(*(p+2));
  354.     endpolygon();
  355.     }
  356.  
  357.     blendfunction(BF_ONE, BF_ZERO);
  358.     zwritemask(0xffffff);
  359.  
  360.     popmatrix();
  361. }
  362.  
  363.  
  364. draw_exp_ci(int frame)
  365. {
  366.     int i, c, j;
  367.     float s;
  368.     float **p;
  369.     static float t0[3] = { .2, .2, -.1},
  370.          t1[3] = {-.2, 0.0, 0.0},
  371.          t2[3] = {.2, -.2, .1};
  372.  
  373.     backface(1);
  374.     pushmatrix();
  375.  
  376.     s = (frame + 1.0) * 3.0;
  377.     scale(s, s, s);
  378.  
  379.     setpattern(EXPL_PAT0 + (frame>>2));
  380.  
  381.     for (i = 0; i < 100; i++)
  382.     {
  383.     pushmatrix();
  384.     translate(exp_pnt[i][0], exp_pnt[i][1], exp_pnt[i][2]);
  385.     switch (i % 3)
  386.     {
  387.         case 0:
  388.         color(ci_table[C_RED]);
  389.         break;
  390.         case 1:
  391.         color(ci_table[C_ORANGE]);
  392.         break;
  393.         case 2:
  394.         color(ci_table[C_DRED]);
  395.         break;
  396.     }
  397.     rotate((i%20)<<8, 'x');
  398.     rotate((i%20)<<7, 'y');
  399.     bgnpolygon();
  400.     v3f(t0);
  401.     v3f(t1);
  402.     v3f(t2);
  403.     endpolygon();
  404.     popmatrix();
  405.     }
  406.  
  407.     rotate(frame<<10, 'x');
  408.     rotate(frame<<6, 'y');
  409.  
  410.     /*
  411.      *  fire ball
  412.      */
  413.     for (i=0, p = exp_p; i < EXP_TRI; i++, p += 3)
  414.     {
  415.     bgnpolygon();
  416.     color(expv_cols[expref[i][0]]);
  417.     v3f(*p);
  418.     color(expv_cols[expref[i][1]]);
  419.     v3f(*(p+1));
  420.     color(expv_cols[expref[i][2]]);
  421.     v3f(*(p+2));
  422.     endpolygon();
  423.     }
  424.  
  425.     popmatrix();
  426.     backface(0);
  427.     setpattern(0);
  428. }
  429.  
  430.  
  431. /*
  432.  *  draw_missile() draws a missile it's contrail and it's explosion.
  433.  *  RGB version
  434.  */
  435. draw_missile(p, ph)
  436.     Plane p;
  437.     Plane_hist ph;
  438. {
  439.     float tmpv1[4];
  440.     float tmpv2[4];
  441.     int i, j, k;
  442.     float vx, vy, vz, d1, d2;
  443.     int myrot, mxrot;
  444.     float px, py, pz, qx, qy, qz, nx, ny, nz, nm;
  445.     Plane pp = planes[0];
  446.  
  447.     if (p->mstatus)            /* if launched */
  448.     {
  449.     if (p->mstatus <= MEXPLODE)    /* if exploding */
  450.     {
  451.         pushmatrix();
  452.         translate(p->mx, p->my, p->mz);
  453.         draw_exp(19 - (p->mstatus - 1));
  454.         popmatrix();
  455.     }
  456.     else if (p->mtype != TYPE_CANNON)
  457.     {
  458.         if (!ph->malive)    /* just launched */
  459.         {
  460.         ph->mtpos = ph->mtspos = ph->mtlen = 0;
  461.         ph->mt[0][0] = p->last_mx;
  462.         ph->mt[0][1] = p->last_my;
  463.         ph->mt[0][2] = p->last_mz;
  464.         }
  465.  
  466.         /*
  467.          *  compute missile direction
  468.          */
  469.         vx = p->mx - p->last_mx;
  470.         vy = p->my - p->last_my;
  471.         vz = p->mz - p->last_mz;
  472.  
  473.         d1 = sqrt(vx*vx + vz*vz);
  474.         d2 = sqrt(vx*vx + vy*vy + vz*vz);
  475.  
  476.         if (d1 != 0.0)
  477.         vx /= d1;
  478.         else
  479.         vx = 1.0;
  480.  
  481.         vy /= d2;
  482.  
  483.         myrot = xasin(vx);
  484.         if (vz > 0)
  485.         myrot = ((vx > 0)? 1800 : -1800) - myrot;
  486.  
  487.         mxrot = xasin(vy);
  488.  
  489.         pushmatrix();
  490.         translate(p->mx, p->my, p->mz);
  491.         rotate(-myrot, 'y');
  492.         rotate(mxrot, 'x');
  493.  
  494.         drawobj(swobj, 0x1);
  495.  
  496.         popmatrix();
  497.  
  498.         if (ph->mt[ph->mtpos][0] != p->mx ||
  499.         ph->mt[ph->mtpos][1] != p->my ||
  500.         ph->mt[ph->mtpos][2] != p->mz)
  501.         {
  502.         ph->mtpos++;
  503.         ph->mtpos %= MT_MAX;
  504.         if (ph->mtlen == MT_MAX-1)
  505.             ph->mtspos = (ph->mtpos + 1) % MT_MAX;
  506.         else
  507.             ph->mtlen++;
  508.  
  509.         ph->mt[ph->mtpos][0] = p->mx;
  510.         ph->mt[ph->mtpos][1] = p->my;
  511.         ph->mt[ph->mtpos][2] = p->mz;
  512.         }
  513.  
  514.         blendfunction(BF_SA, BF_MSA);
  515.  
  516.         set_matalpha(MAT_MTRAIL, 0.8);
  517.         set_matemission(MAT_MTRAIL, 1.0, 0.2, 0.0);
  518.         setmaterial(MAT_MTRAIL);
  519.         bgntmesh();
  520.  
  521.         for (i = ph->mtpos, k=0; i != ph->mtspos; i = j, k++)
  522.         {
  523.         j = i - 1;
  524.         if (j < 0)
  525.             j = MT_MAX-1;
  526.  
  527.         if (k == 2)
  528.             set_matemission(MAT_MTRAIL, 0.0, 0.0, 0.0);
  529.         else if (k >= 22)
  530.             set_matalpha(MAT_MTRAIL, (29 - k) * 0.1);
  531.  
  532.         n3f(n_up);
  533.         /*
  534.          *  compute the normal
  535.          */
  536.         px = ph->mt[j][X] - ph->mt[i][X];
  537.         py = ph->mt[j][Y] - ph->mt[i][Y];
  538.         pz = ph->mt[j][Z] - ph->mt[i][Z];
  539.  
  540.         qx = ph->mt[i][X] - current_eye[X];
  541.         qy = ph->mt[i][Y] - current_eye[Y];
  542.         qz = ph->mt[i][Z] - current_eye[Z];
  543.  
  544.         nx = py*qz - pz*qy;
  545.         ny = pz*qx - px*qz;
  546.         nz = px*qy - py*qx;
  547.  
  548.         /*
  549.          * normalize the normal to length 1
  550.          */
  551.         if (i == ph->mtpos)
  552.             nm = sqrt(nx*nx + ny*ny + nz*nz) * 2.0;
  553.         else
  554.             nm = sqrt(nx*nx + ny*ny + nz*nz) * 0.4;
  555.  
  556.         nx /= nm;
  557.         ny /= nm;
  558.         nz /= nm;
  559.  
  560.         tmpv1[0] = ph->mt[i][0] + nx;
  561.         tmpv1[1] = ph->mt[i][1] + ny;
  562.         tmpv1[2] = ph->mt[i][2] + nz;
  563.         v3f(tmpv1);
  564.         tmpv2[0] = ph->mt[i][0] - nx;
  565.         tmpv2[1] = ph->mt[i][1] - ny;
  566.         tmpv2[2] = ph->mt[i][2] - nz;
  567.         v3f(tmpv2);
  568.         }
  569.  
  570.         if (k >= 22)
  571.         set_matalpha(MAT_MTRAIL, (29 - k) * 0.1);
  572.         n3f(n_up);
  573.         tmpv1[0] = ph->mt[i][0] + nx;
  574.         tmpv1[1] = ph->mt[i][1] + ny;
  575.         tmpv1[2] = ph->mt[i][2] + nz;
  576.         v3f(tmpv1);
  577.         tmpv2[0] = ph->mt[i][0] - nx;
  578.         tmpv2[1] = ph->mt[i][1] - ny;
  579.         tmpv2[2] = ph->mt[i][2] - nz;
  580.         v3f(tmpv2);
  581.  
  582.         endtmesh();
  583.  
  584.         blendfunction(BF_ONE, BF_ZERO);
  585.     }
  586.     else
  587.     {
  588.         cpack(cpack_table[C_RED]);
  589.         lsuspend(TRUE);
  590.         move(p->last_mx, p->last_my, p->last_mz);
  591.         draw(p->mx, p->my, p->mz);
  592.         lsuspend(FALSE);
  593.     }
  594.     }
  595.  
  596.     ph->malive = p->mstatus;
  597. }
  598.  
  599.  
  600. /*
  601.  *  draw_missile_ci() draws a missile it's contrail and it's explosion.
  602.  *  color_index version
  603.  */
  604. draw_missile_ci(p, ph)
  605.     Plane p;
  606.     Plane_hist ph;
  607. {
  608.     float tmpv1[4];
  609.     float tmpv2[4];
  610.     int i, j, k;
  611.     float vx, vy, vz, d1, d2;
  612.     int myrot, mxrot;
  613.     float px, py, pz, qx, qy, qz, nx, ny, nz, nm;
  614.     Plane pp = planes[0];
  615.  
  616.     if (p->mstatus)            /* if launched */
  617.     {
  618.     if (p->mstatus <= MEXPLODE)    /* if exploding */
  619.     {
  620.         pushmatrix();
  621.         translate(p->mx, p->my, p->mz);
  622.         draw_exp_ci(19 - (p->mstatus - 1));
  623.         popmatrix();
  624.     }
  625.     else if (p->mtype != TYPE_CANNON)
  626.     {
  627.         if (!ph->malive)    /* just launched */
  628.         {
  629.         ph->mtpos = ph->mtspos = ph->mtlen = 0;
  630.         ph->mt[0][0] = p->last_mx;
  631.         ph->mt[0][1] = p->last_my;
  632.         ph->mt[0][2] = p->last_mz;
  633.         }
  634.  
  635.         /*
  636.          *  compute missile direction
  637.          */
  638.         vx = p->mx - p->last_mx;
  639.         vy = p->my - p->last_my;
  640.         vz = p->mz - p->last_mz;
  641.  
  642.         d1 = sqrt(vx*vx + vz*vz);
  643.         d2 = sqrt(vx*vx + vy*vy + vz*vz);
  644.  
  645.         if (d1 != 0.0)
  646.         vx /= d1;
  647.         else
  648.         vx = 1.0;
  649.  
  650.         vy /= d2;
  651.  
  652.         myrot = xasin(vx);
  653.         if (vz > 0)
  654.         myrot = ((vx > 0)? 1800 : -1800) - myrot;
  655.  
  656.         mxrot = xasin(vy);
  657.  
  658.         pushmatrix();
  659.         translate(p->mx, p->my, p->mz);
  660.         rotate(-myrot, 'y');
  661.         rotate(mxrot, 'x');
  662.  
  663.         drawobj(swobj, 0x1);
  664.  
  665.         popmatrix();
  666.  
  667.         /* do that contrail thing */
  668.  
  669.         if (ph->mt[ph->mtpos][0] != p->mx ||
  670.         ph->mt[ph->mtpos][1] != p->my ||
  671.         ph->mt[ph->mtpos][2] != p->mz)
  672.         {
  673.         ph->mtpos++;
  674.         ph->mtpos %= MT_MAX;
  675.         if (ph->mtlen == MT_MAX-1)
  676.             ph->mtspos = (ph->mtpos + 1) % MT_MAX;
  677.         else
  678.             ph->mtlen++;
  679.  
  680.         ph->mt[ph->mtpos][0] = p->mx;
  681.         ph->mt[ph->mtpos][1] = p->my;
  682.         ph->mt[ph->mtpos][2] = p->mz;
  683.         }
  684.  
  685.         setpattern(EXPL_PAT0 + 2);
  686.  
  687.         shademodel(GOURAUD);
  688.         bgntmesh();
  689.         color(ci_table[C_MC_FLAME]);
  690.  
  691.         for (i = ph->mtpos, k=0; i != ph->mtspos; i = j, k++)
  692.         {
  693.         j = i - 1;
  694.         if (j < 0)
  695.             j = MT_MAX-1;
  696.  
  697.         /*
  698.          *  compute the normal
  699.          */
  700.         px = ph->mt[j][X] - ph->mt[i][X];
  701.         py = ph->mt[j][Y] - ph->mt[i][Y];
  702.         pz = ph->mt[j][Z] - ph->mt[i][Z];
  703.  
  704.         qx = ph->mt[i][X] - current_eye[X];
  705.         qy = ph->mt[i][Y] - current_eye[Y];
  706.         qz = ph->mt[i][Z] - current_eye[Z];
  707.  
  708.         nx = py*qz - pz*qy;
  709.         ny = pz*qx - px*qz;
  710.         nz = px*qy - py*qx;
  711.  
  712.         /*
  713.          * normalize the normal to length 1
  714.          */
  715.         if (i == ph->mtpos)
  716.             nm = sqrt(nx*nx + ny*ny + nz*nz) * 2.0;
  717.         else
  718.             nm = sqrt(nx*nx + ny*ny + nz*nz) * 0.4;
  719.  
  720.         nx /= nm;
  721.         ny /= nm;
  722.         nz /= nm;
  723.  
  724.         tmpv1[0] = ph->mt[i][0] + nx;
  725.         tmpv1[1] = ph->mt[i][1] + ny;
  726.         tmpv1[2] = ph->mt[i][2] + nz;
  727.         tmpv2[0] = ph->mt[i][0] - nx;
  728.         tmpv2[1] = ph->mt[i][1] - ny;
  729.         tmpv2[2] = ph->mt[i][2] - nz;
  730.  
  731.         if (k != 1)
  732.         {
  733.             v3f(tmpv1);
  734.             v3f(tmpv2);
  735.  
  736.         }
  737.         else
  738.         {
  739.             color(ci_table[C_MC_TRAIL]);
  740.             v3f(tmpv1);
  741.             v3f(tmpv2);
  742.             endtmesh();
  743.             shademodel(FLAT);
  744.             bgntmesh();
  745.             v3f(tmpv1);
  746.             v3f(tmpv2);
  747.         }
  748.         }
  749.  
  750.         endtmesh();
  751.     }
  752.     else
  753.     {
  754.         linewidth(2);
  755.         color(ci_table[C_RED]);
  756.         move(p->last_mx, p->last_my, p->last_mz);
  757.         draw(p->mx, p->my, p->mz);
  758.         linewidth(1);
  759.     }
  760.     }
  761.     setpattern(0);
  762.  
  763.     ph->malive = p->mstatus;
  764. }
  765.  
  766.  
  767.